module ecs {
    export class CachedInjector implements Injector{
        private _cache: InjectionCache = InjectionCache.get();
        private _fieldHandler: FieldHandler;
        private _injectables: {[s: string]: Object};

        public getRegistered<T>(id: string): T {
            return this._injectables[id] as T;
        }

        public initialize(world: World, injectables: { [s: string]: Object; }) {
            this._injectables = injectables;
            if (this._fieldHandler == null)
                this._fieldHandler = new FieldHandler(this._cache);

            this._fieldHandler.initialize(world, injectables);
        }

        public inject(target: Object) {
            try {
                // let cachedClass = this._cache.getCachedClass(target);
                // let declaredFields = this.getAllInjectableFields(cachedClass);
                // for (let i = 0, s = declaredFields.length; s > i; i ++){
                //     let field = declaredFields[i];
                //     this.injectField(target, field, false);
                // }
            }catch(err){
                throw new Error("Error while wiring" + err);
            }
        }

        private injectField(target: Object, field: Field, faileOnNotInjected: boolean){
            // TODO: resolve field
        }

        private getAllInjectableFields(cachedClass: CachedClass): Field[]{
            let declaredFields = cachedClass.allFields;
            if (declaredFields == null){
                let fieldList = new Array<Field>();
                let clazz = cachedClass.clazz;
                this.collectDeclaredInjectableFields(fieldList, clazz);

                while (cachedClass.injectInherited){
                    this.collectDeclaredInjectableFields(fieldList, clazz);
                }

                cachedClass.allFields = declaredFields = fieldList;
            }

            return declaredFields;
        }

        private collectDeclaredInjectableFields(fieldList: Array<Field>, clazz: any){
            try {
                // TODO: 判断是否为skip
            } catch (err){
                throw new Error("Error while wiring" + err);
            }
        }

        public isInjectable(target: Object): boolean {
            throw new Error("Method not implemented.");
        }

        public setFieldHandler(fieldHandler: FieldHandler): Injector {
            throw new Error("Method not implemented.");
        }

    }
}